import numpy as np
from scipy.stats import norm

class GaussianNaiveBayes:
    def fit(self, X, y):
        self.classes = np.unique(y)
        self.mean = {}
        self.var = {}
        self.priors = {}

        for c in self.classes:
            X_c = X[y == c]
            self.mean[c] = np.mean(X_c, axis=0)
            self.var[c] = np.var(X_c, axis=0)
            self.priors[c] = X_c.shape[0] / X.shape[0]

    def _likelihood(self, x, mean, var):
        return norm.pdf(x, mean, np.sqrt(var))

    def _posterior(self, X_row, c):
        likelihood = np.sum(np.log(self._likelihood(X_row, self.mean[c], self.var[c])))
        return likelihood + np.log(self.priors[c])

    def predict(self, X):
        predictions = [self._predict(x) for x in X]
        return np.array(predictions)

    def _predict(self, x):
        posteriors = {c: self._posterior(x, c) for c in self.classes}
        return max(posteriors, key=posteriors.get)
